package com.Advance.InnerClass_;

public class InnerClass_Detail {
    public static void main(String[] args) {
        System.out.println("======局部内部类======");
        OuterClass01 outerClass01 = new OuterClass01();
        outerClass01.f1();
        System.out.println(outerClass01);
        //外部其他类无法访问内部类
//        outerClass01.f2();
        System.out.println("======================");
        //成员内部类
        System.out.println("======成员内部类======");
        //对于成员内部类可以通过外部其他类来访问内部类
        //第一种方式：
        OuterClass02 outerClass02 = new OuterClass02();
       OuterClass02.InnerClass02 innerClass02 = outerClass02.new InnerClass02();
       innerClass02.f3();
        //第二种方式：在外部类中创建一个方法，返回一个对象实例
        OuterClass02.InnerClass02 innerClass = outerClass02.getInnerClass();
        innerClass.f3();
        System.out.println("=============");
        //静态内部类
        System.out.println("======静态内部类======");
        OuterClass03 outerClass03 = new OuterClass03();
        outerClass03.f4();
        //外部其他类访问静态内部类，静态内部类可以通过类名直接访问，前提满足访问权限
        //方式一:
        OuterClass03.InnerClass03 innerClass03 = new OuterClass03.InnerClass03();
        innerClass03.f3();
        //方式二：编写一个方法
        OuterClass03.InnerClass03 innerClass1 = outerClass03.getInnerClass();
        innerClass.f3();
        //还可以通过编写一个静态方法去访问
        //方法三:
        OuterClass03.InnerClass03 innerClass1_ = OuterClass03.getInnerClass_();
        innerClass1.f3();
    }
}
//局部内部类
class OuterClass01 {
    private int n1 = 100;
    private void ok() {
        System.out.println("你好");
    }
    public void f1(){
        //可以通过在内部类中使用final，
        final class InnerClass01{
            int n1 = 1000;
            public void f2(){
                System.out.println(n1);//局部类访问外部类属性
                ok();
                System.out.println(OuterClass01.this);//验证与外部的outerClass是否为同一个对象
            }
//如果外部类和局部内部类的成员重名时，默认遵循就近原则，如果想访问外部类的成员，
// 则可以使用（外部类名.this.成员）去访问，其中 外部类名.this 本质就是外部类的对象

        }
        //外部类访问内部类
        InnerClass01 innerClass = new InnerClass01();
        innerClass.f2();
    }
}
//成员内部类
class OuterClass02 {
    private int a1 = 100;
    private void yes() {
        System.out.println("yes");
    }
    //此处可以添加任意访问修饰符，因为在此处是充当成员，并不是局部变量
    class InnerClass02 {
        private int a2 = 1000;
        public void f3() {
            System.out.println("外部类的属性= " + a1 + "内部类属性= " + a2);
            yes();
            //直接访问外部成员
        }
    }
    //作用域：外部类中都能使用这个成员内部类中的方法
    public void f4() {
        InnerClass02 innerClass = new InnerClass02();
        innerClass.f3();//通过创建对象可访问成员内部类中的成员
    }
    public InnerClass02 getInnerClass() {
        return new InnerClass02();
    }

}
class OuterClass03 {
    private int h1 = 100;
    private static int h2 = 1000;
    private static String name = "小明";
    private static void say() {
        System.out.println("hello world");
    }
    //可加任意访问修饰符
    static class InnerClass03 {
        //如果外部类和静态内部类的成员重名时，访问时，
        //遵守就近原则，如果访问外部类成员，使用（外部类名.成员）去访问
        private int a1 = 1000;
        private static String name = "小华";
        public void f3() {
            System.out.println("f3()方法被调用");
//            System.out.println(h1);
            System.out.println(h2);
            say();
            System.out.println(name);
            System.out.println(OuterClass03.name);
        }
        //静态内部类的调用规则同静态方法，无法调用非静态成员

    }
    public void f4() {
        new InnerClass03().f3();
    }
    public InnerClass03 getInnerClass() {
        return new InnerClass03();
    }
    public static InnerClass03 getInnerClass_() {
        return new InnerClass03();
    }
}


